package com.cheryl.springailearn.controller;

import lombok.RequiredArgsConstructor;
import org.springframework.ai.openai.OpenAiAudioSpeechModel;
import org.springframework.ai.openai.OpenAiAudioSpeechOptions;
import org.springframework.ai.openai.OpenAiAudioTranscriptionModel;
import org.springframework.ai.openai.OpenAiAudioTranscriptionOptions;
import org.springframework.ai.openai.api.OpenAiAudioApi;
import org.springframework.ai.openai.audio.speech.SpeechPrompt;
import org.springframework.ai.openai.audio.speech.SpeechResponse;
import org.springframework.ai.openai.audio.transcription.AudioTranscriptionPrompt;
import org.springframework.ai.openai.audio.transcription.AudioTranscriptionResponse;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.FileOutputStream;
import java.io.IOException;

@RequestMapping("/audio")
@RequiredArgsConstructor
@RestController
public class AudioModelController {

    private final OpenAiAudioSpeechModel openAiAudioSpeechModel;

    private final OpenAiAudioTranscriptionModel openAiTranscriptionModel;

    @GetMapping
    public void text2audio() throws IOException {
        OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder()
                .withModel("tts-1")//要使用的模型的 ID。目前只有 tts-1 可用。
                .withVoice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)//用于 TTS 输出的语音。可用选项包括：alloy, echo, fable, onyx, nova, and shimmer.
                .withResponseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)//音频输出的格式。支持的格式包括 mp3、opus、aac、flac、wav 和 pcm。
                .withSpeed(1.0f)//语音合成的速度。可接受的范围是从 0.0（最慢）到 1.0（最快）
                .build();

        //要转换的语音内容
        SpeechPrompt speechPrompt = new SpeechPrompt("你好，这是一个文本到语音的例子。", speechOptions);
        SpeechResponse response = openAiAudioSpeechModel.call(speechPrompt);
        byte[] output = response.getResult().getOutput();
        //将文件输出到指定位置
        writeByteArrayToMp3(output,"/Users/mac/Desktop/project/java");
    }

    public static void writeByteArrayToMp3(byte[] audioBytes, String outputFilePath) throws IOException {
        // 创建FileOutputStream实例
        FileOutputStream fos = new FileOutputStream(outputFilePath+"/audio_demo.mp3");

        // 将字节数组写入文件
        fos.write(audioBytes);

        // 关闭文件输出流
        fos.close();
    }

    @GetMapping("/audio2text")
    public String audio2text(){
        //脚本输出的格式，位于以下选项之一中：json、text、srt、verbose_json 或 vtt。
        OpenAiAudioApi.TranscriptResponseFormat responseFormat = OpenAiAudioApi.TranscriptResponseFormat.TEXT;

        OpenAiAudioTranscriptionOptions transcriptionOptions = OpenAiAudioTranscriptionOptions.builder()
                .withLanguage("en")//输入音频的语言。以 ISO-639-1 格式提供输入语言将提高准确性和延迟。
                .withPrompt("Ask not this, but ask that")//用于指导模型样式或继续上一个音频片段的可选文本。提示应与音频语言匹配。
                .withTemperature(0f)//采样温度，介于 0 和 1 之间。较高的值（如 0.8）将使输出更具随机性，而较低的值（如 0.2）将使其更加集中和确定。如果设置为 0，模型将使用对数概率自动提高温度，直到达到某些阈值。
                .withResponseFormat(responseFormat)//输出格式
                .build();
        //获取当前语音文件
        ClassPathResource audioFile = new ClassPathResource("audio_demo.mp3");
        AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(audioFile, transcriptionOptions);
        AudioTranscriptionResponse response = openAiTranscriptionModel.call(transcriptionRequest);
        return response.getResult().getOutput();
    }
}
